/*
 *  Copyright 2012 yura.
 * 
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 * 
 *       http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *  under the License.
 */

package org.opu.pc.domain;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import org.opu.pc.domain.dao.PublicationDao;
import org.opu.pc.domain.dao.PublisherDao;
import org.opu.pc.domain.domains.Publication;
import org.opu.pc.domain.domains.Publisher;
import org.opu.pc.ui.util.Logger;

/**
 *
 * @author Yuriy Dunko
 */
public class PublicationManagementImpl implements PublicationManagement {

    private Logger logger = Logger.create(PublicationManagementImpl.class);
    private PublicationDao publicationDao;
    private PublisherDao publicatorDao;

    public PublicationManagementImpl(PublicationDao publicationDao,
            PublisherDao publicatorsService) {
        this.publicationDao = publicationDao;
        this.publicatorDao = publicatorsService;
    }

    @Override
    public List<Publication> list() {
        return publicationDao.getList();
    }

    @Override
    public List<Publication> searchByName(String name, Boolean wasApplied) {
        return publicationDao.searchPublicationsByName(name, wasApplied);
    }

    @Override
    public List<Publication> publicationsForPublisher(Integer publicatorId,
            Boolean wasApplied) {
        return publicationDao.getPublicationsForPublisher(
                publicatorId, wasApplied);
    }

    @Override
    public Publication createNew(Publication publication,
            List<Publisher> authors) {
        logger.debug("Creating new publication <" + publication + "> for "
                + "publishers " + authors.toString());

        // 1 - validate
        if (authors == null || authors.isEmpty()){
            throw new IllegalArgumentException("Publication must have at least"
                    + " one author.");
        }

        // 2 - ensure authors
        List<Publisher> publicators = new ArrayList<Publisher>(authors.size());
        for (Publisher p : authors) {
            Publisher author = getByName(p.getName(), p.getSecondName(),
                    p.getLastName());

            if (author == null){
            logger.info(String.format("Publisher [<%S><%S><%S>] will be created",
                    p.getName(), p.getSecondName(), p.getLastName()));
                author = new Publisher();
                author.setName(p.getName());
                author.setSecondName(p.getSecondName());
                author.setLastName(p.getLastName());
                author.setIsStudent(p.getIsStudent());
                publicatorDao.save(author);
            }
            publicators.add(author);
        }

        // 3 - save data
        publication.setPublishers(new HashSet<Publisher>(publicators));

        logger.info(String.format("Publication [<%S>] will be created",
                publication.getName()));
        publicationDao.save(publication);

        return publication;
    }

    @Override
    public void deletePublication(Integer id){
        publicationDao.delete(publicationDao.get(id));
    }

    @Override
    public void updatePublication(Publication publicationBean){
        Publication publication = publicationDao.get(publicationBean.getId());
        publication.setName(publicationBean.getName());
        publication.setPublicationPlace(publicationBean.getPublicationPlace());
        publication.setDate(publicationBean.getDate());
        publication.setConferenceVenue(publicationBean.getConferenceVenue());
        publication.setPageNumberStart(publicationBean.getPageNumberStart());
        publication.setPageNumberStart(publicationBean.getPageNumberEnd());
        publication.setWasApplied(publicationBean.isWasApplied());
        publicationDao.saveOrUpdate(publication);
    }

    private Publisher getByName(String name, String secondName,
            String lastName) {
        List<Publisher> list = publicatorDao.getPublishersByName(name,
                secondName, lastName);

        if (list.isEmpty()){
            logger.info(String.format("Publisher [<%S><%S><%S>] not found.",
                    name, secondName, lastName, list.size()));
            return null;
        }

        if (list.size() > 1){
            // TODO: Handle some how ...
            logger.warning(String.format("Get publisher by name [<%S><%S><%S>],"
                    + " return $d elements, but expect 1.", name, secondName,
                    lastName, list.size()));
        }

        return list.get(0);
    }

    @Override
    public List<Publication> getStudentsPublications(Date start, Date end) {
        return publicationDao.getStudentsPublications(start, end);
    }

    @Override
    public List<Publication> getProfessorPublications(Date start, Date end,
            Integer professorId) {
        return publicationDao.getProfessorPublications(start, end, professorId);
    }
}
